#!/usr/bin/env node

require('dotenv').config();
const path = require('path');
const chalk = require('chalk');
const FTPClient = require('./lib/ftp-client');
const FileWatcher = require('./lib/file-watcher');

class FTPSyncManager {
    constructor() {
        this.config = this.loadConfig();
        this.ftpClient = new FTPClient({
            host: this.config.ftpHost,
            port: this.config.ftpPort,
            user: this.config.ftpUser,
            password: this.config.ftpPassword,
            secure: this.config.ftpSecure,
            passive: this.config.ftpPassive,
            timeout: this.config.ftpTimeout,
            debug: this.config.ftpDebug
        });
        this.fileWatcher = null;
    }

    loadConfig() {
        const requiredEnvVars = ['FTP_HOST', 'FTP_USER', 'FTP_PASSWORD'];
        const missing = requiredEnvVars.filter(varName => !process.env[varName]);
        
        if (missing.length > 0) {
            console.error(chalk.red('❌ 缺少必要的环境变量:'));
            missing.forEach(varName => {
                console.error(chalk.red(`   - ${varName}`));
            });
            console.error(chalk.yellow('\n请复制 .env.example 为 .env 并填入正确的配置信息'));
            process.exit(1);
        }

        const excludePatterns = process.env.EXCLUDE_PATTERNS 
            ? process.env.EXCLUDE_PATTERNS.split(',').map(p => p.trim())
            : [];

        return {
            ftpHost: process.env.FTP_HOST,
            ftpPort: parseInt(process.env.FTP_PORT) || 21,
            ftpUser: process.env.FTP_USER,
            ftpPassword: process.env.FTP_PASSWORD,
            ftpSecure: process.env.FTP_SECURE === 'true',
            ftpPassive: process.env.FTP_PASSIVE !== 'false',
            ftpTimeout: parseInt(process.env.FTP_TIMEOUT) || 30000,
            ftpDebug: process.env.FTP_DEBUG === 'true',
            
            localAddonPath: path.resolve(process.env.LOCAL_ADDON_PATH || '../gs_demo_thinkphp/addons/gs_demo'),
            localAssetsPath: path.resolve(process.env.LOCAL_ASSETS_PATH || '../gs_demo_thinkphp/public/assets/addons/gs_demo'),
            remoteAddonPath: process.env.REMOTE_ADDON_PATH || '/addons/gs_demo',
            remoteAssetsPath: process.env.REMOTE_ASSETS_PATH || '/public/assets/addons/gs_demo',
            
            watchMode: process.env.WATCH_MODE !== 'false',
            syncDelay: parseInt(process.env.SYNC_DELAY) || 1000,
            excludePatterns
        };
    }

    async run() {
        const args = process.argv.slice(2);
        const command = args[0] || 'sync';

        console.log(chalk.blue('🚀 GS Demo FTP同步工具'));
        console.log(chalk.gray('=' .repeat(50)));
        
        this.displayConfig();

        switch (command) {
            case 'sync':
                await this.syncOnce();
                break;
            case 'watch':
            case '--watch':
                await this.startWatching();
                break;
            case 'full-sync':
                await this.fullSync();
                break;
            case 'test':
                await this.testConnection();
                break;
            default:
                this.showHelp();
        }
    }

    displayConfig() {
        console.log(chalk.cyan('配置信息:'));
        console.log(chalk.gray(`  FTP服务器: ${this.config.ftpHost}:${this.config.ftpPort}`));
        console.log(chalk.gray(`  用户名: ${this.config.ftpUser}`));
        console.log(chalk.gray(`  本地插件: ${this.config.localAddonPath}`));
        console.log(chalk.gray(`  远程插件: ${this.config.remoteAddonPath}`));
        console.log(chalk.gray(`  本地资源: ${this.config.localAssetsPath}`));
        console.log(chalk.gray(`  远程资源: ${this.config.remoteAssetsPath}`));
        console.log('');
    }

    async testConnection() {
        console.log(chalk.blue('测试FTP连接...'));
        
        const success = await this.ftpClient.connect();
        if (success) {
            console.log(chalk.green('✅ FTP连接测试成功'));
            await this.ftpClient.disconnect();
        } else {
            console.log(chalk.red('❌ FTP连接测试失败'));
        }
    }

    async syncOnce() {
        console.log(chalk.blue('执行一次性同步...'));
        
        const connected = await this.ftpClient.connect();
        if (!connected) return;

        try {
            await this.uploadChangedFiles();
            console.log(chalk.green('✅ 同步完成'));
        } catch (error) {
            console.error(chalk.red('❌ 同步失败:'), error.message);
        } finally {
            await this.ftpClient.disconnect();
        }
    }

    async fullSync() {
        console.log(chalk.blue('执行完整同步...'));
        
        const connected = await this.ftpClient.connect();
        if (!connected) return;

        try {
            await this.ftpClient.syncDirectory(
                this.config.localAddonPath, 
                this.config.remoteAddonPath,
                { exclude: this.config.excludePatterns }
            );
            
            await this.ftpClient.syncDirectory(
                this.config.localAssetsPath, 
                this.config.remoteAssetsPath,
                { exclude: this.config.excludePatterns }
            );
            
            console.log(chalk.green('✅ 完整同步完成'));
        } catch (error) {
            console.error(chalk.red('❌ 完整同步失败:'), error.message);
        } finally {
            await this.ftpClient.disconnect();
        }
    }

    async startWatching() {
        console.log(chalk.blue('启动文件监控模式...'));
        
        const connected = await this.ftpClient.connect();
        if (!connected) return;

        this.fileWatcher = new FileWatcher(this.config, this.ftpClient);
        
        process.on('SIGINT', () => {
            console.log(chalk.yellow('\n收到中断信号，正在停止...'));
            this.cleanup();
            process.exit(0);
        });

        process.on('SIGTERM', () => {
            console.log(chalk.yellow('\n收到终止信号，正在停止...'));
            this.cleanup();
            process.exit(0);
        });

        this.fileWatcher.start();
        
        console.log(chalk.green('✅ 监控已启动，只会在文件变化时上传，按 Ctrl+C 停止'));
        console.log(chalk.yellow('📝 提示：如需初次完整同步，请运行 npm run full-sync'));
    }

    async uploadChangedFiles() {
        const fs = require('fs');
        const { execSync } = require('child_process');
        
        try {
            const gitStatus = execSync('git status --porcelain', { encoding: 'utf8', cwd: process.cwd() });
            const changedFiles = gitStatus
                .split('\n')
                .filter(line => line.trim())
                .map(line => line.substring(3))
                .filter(file => 
                    file.startsWith('../gs_demo_thinkphp/addons/gs_demo/') ||
                    file.startsWith('../gs_demo_thinkphp/public/assets/addons/gs_demo/') ||
                    file.startsWith('gs_demo_thinkphp/addons/gs_demo/') ||
                    file.startsWith('gs_demo_thinkphp/public/assets/addons/gs_demo/')
                );

            if (changedFiles.length === 0) {
                console.log(chalk.yellow('没有检测到文件变更'));
                return;
            }

            console.log(chalk.cyan(`发现 ${changedFiles.length} 个变更文件:`));
            changedFiles.forEach(file => console.log(chalk.gray(`  ${file}`)));

            for (const file of changedFiles) {
                if (!fs.existsSync(file)) continue;

                let remotePath;
                if (file.startsWith('../gs_demo_thinkphp/addons/gs_demo/')) {
                    const relativePath = file.replace('../gs_demo_thinkphp/addons/gs_demo/', '');
                    remotePath = this.config.remoteAddonPath + '/' + relativePath;
                } else if (file.startsWith('../gs_demo_thinkphp/public/assets/addons/gs_demo/')) {
                    const relativePath = file.replace('../gs_demo_thinkphp/public/assets/addons/gs_demo/', '');
                    remotePath = this.config.remoteAssetsPath + '/' + relativePath;
                } else if (file.startsWith('gs_demo_thinkphp/addons/gs_demo/')) {
                    const relativePath = file.replace('gs_demo_thinkphp/addons/gs_demo/', '');
                    remotePath = this.config.remoteAddonPath + '/' + relativePath;
                } else if (file.startsWith('gs_demo_thinkphp/public/assets/addons/gs_demo/')) {
                    const relativePath = file.replace('gs_demo_thinkphp/public/assets/addons/gs_demo/', '');
                    remotePath = this.config.remoteAssetsPath + '/' + relativePath;
                }

                if (remotePath) {
                    await this.ftpClient.uploadFile(file, remotePath);
                }
            }
        } catch (error) {
            console.log(chalk.yellow('无法使用git检测变更，执行完整同步...'));
            await this.fullSync();
        }
    }

    cleanup() {
        if (this.fileWatcher) {
            this.fileWatcher.stop();
        }
        if (this.ftpClient) {
            this.ftpClient.disconnect();
        }
    }

    showHelp() {
        console.log(chalk.cyan('\n用法:'));
        console.log('  node ftp-sync.js [command]');
        console.log('\n命令:');
        console.log('  sync       同步变更的文件 (默认)');
        console.log('  watch      启动文件监控模式');
        console.log('  full-sync  完整同步所有文件');
        console.log('  test       测试FTP连接');
        console.log('\nNPM脚本:');
        console.log('  npm run sync     # 同步变更文件');
        console.log('  npm run dev      # 启动监控模式');
    }
}

if (require.main === module) {
    const manager = new FTPSyncManager();
    manager.run().catch(console.error);
}

module.exports = FTPSyncManager;